from datetime import datetime
from werkzeug.security import generate_password_hash, check_password_hash
from apps import db


class CMSUser(db.Model):
    __tablename__ = 'cms_user'
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    username = db.Column(db.String(50), nullable=False)
    _password = db.Column(db.String(150), nullable=False)
    email = db.Column(db.String(30), nullable=False, unique=True)
    add_time = db.Column(db.DateTime, default=datetime.now)

    def __init__(self, username, password, email):
        self.username = username
        self.password = password
        self.email = email

    @property  # 属性方法，以后此方法就是该类的一个方法，调用也是想获取属性一样调用
    def password(self):
        return self._password

    @password.setter  # 设置密码
    def password(self, raw_password):
        self._password = generate_password_hash(raw_password)

    def check_password(self, raw_password):  # 检查输入的密码和数据库的密码是否一致
        result = check_password_hash(self._password, raw_password)
        return result

    @property
    def permission(self):
        if not self.roles:
            return 0
        all_permissions = 0
        for role in self.roles:
            permissions = role.permissions
            all_permissions |= permissions
        return all_permissions

    def has_permission(self, permission):
        return self.permission & permission == permission

    @property
    def has_delevop(self):
        return self.has_permission(CMSPermission.ALL_PERMISSION)


class CMSPermission(object):
    # 所有权限
    ALL_PERMISSION = 0b11111111
    # 访问权限
    VISITER = 0b00000001
    # 管理帖子权限
    POSTER = 0b00000010
    # 管理评论权限
    COMMENTER = 0b00000100
    # 管理板块权限
    BOARDER = 0b00001000
    # 管理前台用户权限
    FRONTUSER = 0b00010000
    # 管理后台用户权限
    CMSUSER = 0b00100000


"""用户和权限的中间表"""
cms_user_role = db.Table(
    'cms_user_role',
    db.Column('cms_user_id', db.Integer, db.ForeignKey('cms_user.id'), primary_key=True),
    db.Column('cms_role_id', db.Integer, db.ForeignKey('cms_role.id'), primary_key=True)
)


class CMSRole(db.Model):
    """权限表"""
    __tablename__ = 'cms_role'
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    name = db.Column(db.String(20), nullable=True)
    desc = db.Column(db.String(100), nullable=True)
    permissions = db.Column(db.Integer, default=CMSPermission.VISITER)
    add_time = db.Column(db.DateTime, default=datetime.now)

    users = db.relationship('CMSUser', secondary=cms_user_role, backref='roles')


class CMSBanner(db.Model):
    """轮播图表"""
    # __tablename__ = 'cms_banner',
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    img_name = db.Column(db.String(100))
    img_url = db.Column(db.String(200))
    link_url = db.Column(db.String(200), nullable=True)
    priority = db.Column(db.String(2))
    add_time = db.Column(db.DateTime, default=datetime.now)


class CMSBoard(db.Model):
    """板块"""
    __tablename__ = 'cms_board'
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    board_name = db.Column(db.String(100))
    add_time = db.Column(db.DateTime, default=datetime.now)



class CMSArticle(db.Model):
    """帖子"""
    __tablename__ = 'cms_article'
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    article_title = db.Column(db.String(100), nullable=False)
    article_content = db.Column(db.Text, nullable=False)
    board_id = db.Column(db.Integer, db.ForeignKey('cms_board.id'))
    add_time = db.Column(db.DateTime, default=datetime.now)
    author_id = db.Column(db.String(100), db.ForeignKey('front_user.id'), nullable=False)
    author = db.relationship('FrontUser', backref='cms_articles')
    board = db.relationship('CMSBoard', backref='cms_articles')


class HighLightArticlr(db.Model):
    """加精帖子"""
    __tablename__ = 'cms_high'
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    article_id = db.Column(db.Integer, db.ForeignKey('cms_article.id'))
    add_time = db.Column(db.DateTime, default=datetime.now)

    article = db.relationship('CMSArticle', backref='highlight')

